package com.sbr.esbmonitor.activemq.repository.jmx.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.Query;
import javax.management.QueryExp;
import javax.management.ReflectionException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sbr.esbmonitor.activemq.model.Queue;
import com.sbr.esbmonitor.activemq.repository.QueueRepository;
import com.sbr.esbmonitor.activemq.repository.jmx.JMXManager;
import com.sbr.esbmonitor.servicemix.Server;

public class JMXQueueRepository implements QueueRepository {

	private static final Logger LOG = LoggerFactory.getLogger(JMXQueueRepository.class);

	private JMXManager jmxManager = new JMXManager();

	@Override
	public List<Queue> selectAll(Server server) {
		LOG.debug(">>selectAll('{}')",server);

		MBeanServerConnection connection = jmxManager.connect(server);

		List<Queue> queueList = new ArrayList<Queue>();

		String name = null;
		long consumerCount = 0;
		long size = 0;
		try {
			ObjectName objectName = new ObjectName("org.apache.activemq:Type=Queue,*");
			List<ObjectName> queues = new LinkedList<ObjectName>(connection.queryNames(objectName, null));

			for (Iterator<ObjectName> iter = queues.iterator(); iter.hasNext();)
			{
				ObjectName objName = iter.next();
				String keyProps = objName.getCanonicalKeyPropertyListString();
				ObjectName objectInfoName = new ObjectName("org.apache.activemq:" + keyProps);
				name = (String) connection.getAttribute(objectInfoName, "Name");
				consumerCount = (Long) connection.getAttribute(objectInfoName, "ConsumerCount");
				size = (Long) connection.getAttribute(objectInfoName, "QueueSize");

				Queue queue = new Queue();
				queue.setName(name);
				queue.setConsumerCount(consumerCount);
				queue.setQueueSize(size);
				queueList.add(queue);
			}

		} catch (MalformedObjectNameException e) {
			LOG.error("Erreur dans le format de l'URL",e);
		} catch (NullPointerException e) {
			LOG.error("Erreur ",e);
		} catch (AttributeNotFoundException e) {
			LOG.error("Erreur, l'attribut est inconnu",e);
		} catch (InstanceNotFoundException e) {
			LOG.error("Erreur ",e);
		} catch (MBeanException e) {
			LOG.error("Erreur ",e);
		} catch (ReflectionException e) {
			LOG.error("Erreur ",e);
		} catch (IOException e) {
			LOG.error("Erreur ",e);
		}

		return queueList;
	}

	@Override
	public Queue selectByName(String queueName, Server server) {
		LOG.debug(">>selectByName({},{})",queueName,server);

		MBeanServerConnection connection = jmxManager.connect(server);

		String name = null;
		long consumerCount = 0;
		long size = 0;
		Queue queue = null;
		try {
			ObjectName objectName = new ObjectName("org.apache.activemq:Type=Queue,*");
			QueryExp query = Query.match(Query.attr("Name"), Query.value(queueName));
			List<ObjectName> queues = new LinkedList<ObjectName>(connection.queryNames(objectName, query));

			for (Iterator<ObjectName> iter = queues.iterator(); iter.hasNext();)
			{
				ObjectName objName = iter.next();
				String keyProps = objName.getCanonicalKeyPropertyListString();
				ObjectName objectInfoName = new ObjectName("org.apache.activemq:" + keyProps);
				name = (String) connection.getAttribute(objectInfoName, "Name");
				consumerCount = (Long) connection.getAttribute(objectInfoName, "ConsumerCount");
				size = (Long) connection.getAttribute(objectInfoName, "QueueSize");

				queue = new Queue();
				queue.setName(name);
				queue.setConsumerCount(consumerCount);
				queue.setQueueSize(size);
			}

		} catch (MalformedObjectNameException e) {
			LOG.error("Erreur dans le format de l'URL",e);
		} catch (NullPointerException e) {
			LOG.error("Erreur ",e);
		} catch (AttributeNotFoundException e) {
			LOG.error("Erreur, l'attribut est inconnu",e);
		} catch (InstanceNotFoundException e) {
			LOG.error("Erreur ",e);
		} catch (MBeanException e) {
			LOG.error("Erreur ",e);
		} catch (ReflectionException e) {
			LOG.error("Erreur ",e);
		} catch (IOException e) {
			LOG.error("Erreur ",e);
		}

		return queue;
	}

	public void setJmxManager(JMXManager jmxManager) {
		this.jmxManager = jmxManager;
	}

}
